package com.cskaoyan.javase.oop.constructor4;

/**
 * @description: 构造器, 构造方法
 * @author: wuguidong@cskaoyan.onaliyun.com
 **/

/**
 * 例子：
 * ​	创建一个教师类，有课程和年龄两个属性，行为是可以上课
 * ​	思考一下，我们给成员变量赋值的语句，是不是显得冗余？
 * ​	怎么改进？
 * ​	能不能“出厂”的时候就设定好呢？
 *
 * 构造器的语法:
 * 首先它是一个方法
 *
 * [访问权限修饰符] 当前类的类名(参数){
 *     //语句
 * }
 *当前类的类名 必须保持完完全全一致
 *
 * 我现在创建对象没有写参数,这个时候调用的就是无参构造方法
 * 构造方法的作用：构造方法是创建对象的最后一步，是帮助我们给成员变量赋值的。这个方法不是我们自己调用，而是jvm调用的
 *
 * 构造器重要的一些细节：
 * 1，当一个类没有显式的定义构造方法，这个时候会默认提供一个无参构造方法
 * 2，当一个类中显式的定义了有参构造方法，那么就不会提供默认无参构造方法了
 * 重大提示：所以当你在一个类中定义了一个有参构造后，养成好习惯，必须要给这个类添加上无参构造
 * 后面框架当中，有些框架会去自动调用无参构造创建对象
 * 后面继承当中
 *
 * 3，构造方法也是方法，既然是方法，可以方法重载
 *
 * 4，构造其当中也可以使用this关键字
 *  1，可以调用当前类的别的构造方法
 *  语法是this(参数列表)；
 *  特别注意：使用this调用别的构造方法，该this必须在构造方法的第一行，所以只能用一个this
 *  至于为什么？挖个坑，下次再填
 *  2，可以使用this关键字调用当前对象的成员变量和成员方法
 *  如果这种形式使用this，不受限制
 *  注意：构造方法就是专门给成员变量赋值的，所以一般情况不要什么都往里面放，最好的情况下，就让构造方法专注于创建对象，其他的事情不要管
 *
 *
 * 5，构造方法不是普通方法，更不是成员方法，这个方法不是给程序员调用的，而是给jvm调用的
 * 后面有反射，相当于可以间接使用
 *
 *
 */
public class Demo {
    public static void main(String[] args) {
        //创建老师对象
        /*Teacher t1 = new Teacher();
        t1.course = "JavaSE";
        t1.age = 18;

        //还有别的老师
        Teacher t2 = new Teacher();
        t2.course = "LinuxC";
        t2.age = 80;

        Teacher t3 = new Teacher();
        t3.course = "Python";
        t3.age = 8;*/
        //还有非常多老师
        //如果我多了一个老师 就创建一个对象 然后手动赋值, 你烦不烦 TMD烦死了 创建个对象这么多事情
        //我想创建对象的过程中,我就直接赋值

        Teacher t4 = new Teacher("语文", 30);
        /*System.out.println(t4.age);
        System.out.println(t4.course);*/

       /* //这么多构造方法，怎么知道调用哪一个？
        Teacher t3 = new Teacher(16);
        System.out.println(t3.age);
        System.out.println(t3.course);*/


    }
}

class Teacher {
    //定义成员变量
    String course;//课程
    int age;
    //int var;

    //定义成员方法
    public void teach() {
        System.out.println("老师车速飞快的上课!");
    }

    //定义Teacher的构造方法
    public Teacher(){

    }

    //定义有参的构造方法
    public Teacher(String course, int age) {
        //赋值，把方法传入的局部变量 赋值给当前对象的成员变量
        //this.course代表当前对象的course成员变量
        //后面的course是方法传入的参数 局部变量
       /* this.course = course;
        this.age = age;*/
       //使用this关键字调用后面两个单参数的构造方法
       // System.out.println();
        //Call to 'this()' must be first statement in constructor body
        this(course);
        this.age = age;
        //this(age);
        //System.out.println(this.age);
    }

    //定义一个单参数的构造方法
    public Teacher(String course){
        //赋值，把方法传入的局部变量 赋值给当前对象的成员变量
        this.course = course;
    }

    //定义一个单参数的构造方法
    public Teacher(int age){
        //赋值，把方法传入的局部变量 赋值给当前对象的成员变量
        this.age = age;
    }

   /* //定义一个单参数的构造方法
    public Teacher(int var){
        //赋值，把方法传入的局部变量 赋值给当前对象的成员变量
        this.var = var;
    }*/
}
